<?php
namespace modules\game\services;

use modules\game\services\method\IMethod;
use modules\game\services\observer\PokerJoiner;

class Strategy{

	public $methodNameSpace = Rule::METHOD_NAMESPACE;
	public function methodOrder(){
		$base1 = [
			Rule::SINGLE_P_STRAIGHT ,//先打顺子
			Rule::DOUBLE_P_STRAIGHT	,
			Rule::THREE_P_BY_ONE    ,
			Rule::THREE_P_STRAIGHT	,
		];
		$base2 = [
			Rule::SINGLE_P          ,//后打单张
			Rule::DOUBLE_P			,
			Rule::THREE_P			,
		];
		$king = [
			Rule::FOUR_P_BY_TWO     ,
			Rule::FOUR_P			,
			Rule::TWO_KING          ,
		];
		shuffle($base1);
		shuffle($base2);
		return array_merge($base1,array_merge($base2,$king));
	}
	//一方牌已出完
	public function isOver(Person $person){
		if(Person::$_noPoker){
			return PokerJoiner::$_isEnd = true;
		}
		return false;
	}
	//再次轮到自己出牌
	public function isTurnSelf(Person $person){
		if( $person->_rule->_outPoker && 
			!array_diff( $person->_rule->_outPoker,$person->_lastPoker))
		{
			$person->_isPower = true;
			$person->_rule->_outPoker = [];
			return true;
		}
		return false;
	}
	//出牌
	public function out(Person $person){
		if($this->isOver($person)) return;
		PokerJoiner::$_pokerTime++;//每出牌一次才算一轮
		echo "=========第（".PokerJoiner::$_pokerTime."）波出牌========<br>";
		$chunk = $this->generate($person->_mypoker);
		$methods = $this->methodOrder();
		foreach( $methods as $method){
			$class = $this->methodNameSpace . $method;
			$poker = $class::getInstance()->out($chunk);
			if($poker){
				$person->_mypoker = array_diff($person->_mypoker, $poker);//一副牌不可能有两张一样的
				$person->_lastPoker = $poker;
				$person->_rule->_accordMethod = $method;
				$person->_rule->_outPoker = $poker;
				$person->_isPower = false;//出牌权收回
				$person->_rule->_isKingPoker = $person->_isKing;
				if(empty($person->_mypoker)){
					Person::$_noPoker = true;
					Person::$_winner  = $person;
				}
				echo '出牌人:'.$person->_name.'<br>';
				echo '出牌:'.json_encode($poker).'<br>';
				break;
			}
		}
	}
	//压牌
	public function suppress(Person $person){
		//一方牌已出完
		if($this->isOver($person)) return;
		//一次轮询，出牌无人压住
		if($this->isTurnSelf($person)) return;
		$myChunk = $this->generate($person->_mypoker);
		$opponentChunk = $this->generate($person->_rule->_outPoker);
		$method = $person->_rule->_accordMethod;
		$class = $this->methodNameSpace . $method;
		$poker = $class::getInstance()->suppress($myChunk,$opponentChunk,$this->forceTactic($person));
		if(IMethod::$_forceMethod){//强制出牌 炸弹
			$person->_rule->_accordMethod = IMethod::$_forceMethod;
			IMethod::$_forceMethod = '';
		}
		if($poker){//压住
			$person->_mypoker = array_diff($person->_mypoker, $poker);//一副牌不可能有两张一样的
			$person->_lastPoker = $poker;
			$person->_rule->_outPoker = $poker;
			$person->_rule->_isKingPoker = $person->_isKing;
			if(empty($person->_mypoker)){
				Person::$_noPoker = true;
				Person::$_winner  = $person;
			}
			echo '***压牌人:'.$person->_name.'<br>';
			echo '***压牌:'.json_encode($poker).'<br>';
			
		}else{//压不住
			$person->_lastPoker = [];
			echo '&&&'.$person->_name.'要不起&&&<br>';
		}
	}
	//
	public function forceTactic(Person $person){
		if($person->_isKing){//地主
			return true;
		}
		//以下说明是农民
		if($person->_rule->_isKingPoker){//上个出牌人 是否地主
			return true;
		}
		return false;
	}
	//模块化生成牌
	public function generate(Array $userPoker){
		$chunk = [];
		foreach($userPoker as $val){
			$key = floor($val / 10);
			if(isset($chunk[$key])){
				$chunk[$key][] = $val;
			}else{
				$chunk[$key] = [$val];
			}
		}
		ksort($chunk);
		return $chunk;
	}
}